package se.sll.itintegration.catalogue.capacity.ejb;

import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import lombok.extern.slf4j.Slf4j;
import se.sll.itintegration.catalogue.capacity.entity.CareUnitReferenceEntity;

/**
 *
 * @author Jiri Uosukainen
 */
@Slf4j
@Stateless
public class NotificationSupportEjb {
    
    
    @PersistenceContext(unitName = "capacityPU")
    private EntityManager em;
    
    

    /**
     * Finds units with capacities expiring within the given amount of days
     * @param daysFromNow The number of days from now
     * @return A set of unitIds (HSAID)
     */
    public Set<String> findExpiring(int expiresWithinDays){
        log.debug("findExpiring(): ENTER");
        
        Set<String> units = findUnitIdsWithTimesAboutToExpire(getExpiresDate(expiresWithinDays));

        log.debug("findExpiring(): EXIT");
        return units;
    }    
    
    /**
     * Finds care units having capacity entities that expire before the given date.
     * I.e. capacity.validTo is before expiresBefore
     * @param expiresBefore The first invalid day
     * @return A set of unit HSAID having capacities expiring before the given date. 
     */
    private Set<String> findUnitIdsWithTimesAboutToExpire(Date expiresBefore){
        log.debug("findUnitIdsWithTimesAboutToExpire(): ENTER");
        Set<String> set = null;
        
        log.debug("Search DB for waiting times expiring before: {}", new Object[]{expiresBefore.toString()});
        
        String qs = "SELECT DISTINCT cur FROM CareUnitReferenceEntity cur, IN (cur.product) pr, IN (pr.capacity) c WHERE c.validTo < :expiresBefore";
        TypedQuery<CareUnitReferenceEntity> query = em.createQuery(qs, CareUnitReferenceEntity.class);
        query.setParameter("expiresBefore", expiresBefore);
        List<CareUnitReferenceEntity> curList = query.getResultList();

        if (curList != null) {
            log.debug("Found number of HCU with expiring wating times: {}", new Object[]{curList.size()});
            if (!curList.isEmpty()) {
                set = new HashSet<String>();
                for (CareUnitReferenceEntity cur : curList) {
                    set.add(cur.getHsaID());
                }
            }
        }
        log.debug("findUnitIdsWithTimesAboutToExpire(): EXIT");
        return set;
    }

    /**
     * Calculates the first day of expiration to look for
     * @param daysFromToday
     * @return The first day of expiration
     */
    private Date getExpiresDate(int daysFromToday) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR_OF_DAY, cal.getActualMinimum(Calendar.HOUR_OF_DAY));
        cal.set(Calendar.MINUTE, cal.getActualMinimum(Calendar.MINUTE));
        cal.set(Calendar.SECOND, cal.getActualMinimum(Calendar.SECOND));
        cal.set(Calendar.MILLISECOND, cal.getActualMinimum(Calendar.MILLISECOND));
        cal.add(Calendar.DATE, daysFromToday);
        
//        cal.add(Calendar.YEAR, -3); //FIXME Test only remove this
        
        return cal.getTime();
    }
}
